package physics.component;

import java.awt.Color;
import java.awt.Graphics2D;
import physics.Force;
import physics.Simulation;


/**
 * A spring that also expands and contracts based on a sinusoidal movement.
 *
 * @author Kevin Gao, Connor Gordon
 */
public class Muscle extends Spring {
    private static final int WIDTH = 16;
    private static final int HEIGHT = 16;
    private static final double INCREMENT = 0.01;
    private final double myAmplitude;
    private double myPhase;

    /**
     * Constructor for Muscle.
     *
     * @param start One of the Masses that the muscle connects
     * @param end One of the Masses that the muscle connects
     * @param length The initial rest length
     * @param kVal The spring constant
     * @param amplitude The amplitude for the sinusoid controlling the muscle
     */
    public Muscle (final Mass start, final Mass end, final double length,
            final double kVal, final double amplitude) {
        super(start, end, length, kVal);
        myAmplitude = amplitude;
        myPhase = 0;
    }

    @Override
    public final void drawShape (final Graphics2D pen) {
        super.drawShape(pen);
        pen.fillOval((getStartX() + getEndX()) / 2 - WIDTH / 2,
                (getStartY() + getEndY()) / 2 - HEIGHT / 2, WIDTH, HEIGHT);
    }

    @Override
    public final void update (final Simulation canvas, final double dt) {
        calculateDxDy();
        double angle = Force.angleBetween(getDx(), getDy());
        double magnitude = (getRestLength() * myAmplitude * Math.sin(myPhase)
                - Force.distanceBetween(getDx(), getDy())) * getK();
        Force f = new Force(angle, magnitude);
        getStartMass().applyForce(f);
        f.negate();
        getEndMass().applyForce(f);
        myPhase += INCREMENT;
    }

    @Override
    protected final void determineColor (final Graphics2D pen) {
        pen.setColor(Color.CYAN);
    }

}
